#include <iostream>

#include "SServer.h"
#include "SMsg.h"

#define LOGGER_NAME "shadow.sscf.sserver"

using std::cout;
using std::endl;

SServer::SServer() {
		_logger = log4cxx::Logger::getLogger(LOGGER_NAME);
		_smsg_max_packet_size = -1;
		_smsg_recv_timeout = -1;
		_smsg_send_timeout = -1;
}

SServer::~SServer() { }

int SServer::sscf_read_event_handler(SSocket * s, void * arg) {
		SServer * svr = (SServer *)arg;
		string t, buf, tt;
		while (true) {
				int res = s->recv_any(t, svr->_smsg_recv_timeout);
				if (res < 0) return -1000;
				buf += t;
				int buf_size = buf.size();
				if (buf_size < 2) continue;
				if (svr->_smsg_max_packet_size > 0 && buf_size > svr->_smsg_max_packet_size) {
						LOG4CXX_ERROR(svr->_logger, "reach max smsg packet size, limit:" << svr->_smsg_max_packet_size << \
										", current size:" << buf_size);
						return -1001;
				}
				tt = buf.substr(buf_size - strlen(SSERVER_PROTO_SMSG_SEP));
				if (tt == SSERVER_PROTO_SMSG_SEP) {
						SMsg in_smsg, out_smsg;
						res = in_smsg.unpack(buf.c_str(), buf.size() - strlen(SSERVER_PROTO_SMSG_SEP));
						if (res < 0) {
								LOG4CXX_ERROR(svr->_logger, "parse smsg error, res:" << res << ", content:" << buf);
								return -1002;
						}
						res = svr->handle_smsg(s, in_smsg, out_smsg);
						if (res < 0) {
								LOG4CXX_ERROR(svr->_logger, "handle smsg fail, res:" << res << ", content:" << buf);
								return -1003;
						}
						string out_buf;
						res = out_smsg.pack(out_buf);
						if (out_buf.size() > 0) {
								out_buf.append(SSERVER_PROTO_SMSG_SEP, strlen(SSERVER_PROTO_SMSG_SEP));
								res = s->send_all(out_buf.c_str(), out_buf.size(), svr->_smsg_send_timeout);
								if (res < 0) {
										LOG4CXX_ERROR(svr->_logger, "send back smsg reply error, res:" << res);
										return -1004;
								}
								return 1;
						}
						return 1;

				}
		}
		return -1003;
}


int SServer::init(int listen_port, int max_thread_num, int socket_idel_timeout, int smsg_recv_timeout, \
				int smsg_send_timeout, int smsg_max_packet_size) {
		_smsg_recv_timeout = smsg_recv_timeout;
		_smsg_send_timeout = smsg_send_timeout;
		_smsg_max_packet_size = smsg_max_packet_size;
		return _sscf.init(listen_port, max_thread_num, socket_idel_timeout, sscf_read_event_handler, this);
}

int SServer::handle_smsg(SSocket * s, SMsg & in_smsg, SMsg & out_smsg) {
		string in_buf;
		in_smsg.pack(in_buf);
		cout << "smsg arrived:" << in_buf << endl;
		out_smsg.put("reply", 88);
		return 1;
}	

int SServer::start_svc() {
		return _sscf.start_svc();
}
